package com.loadagent.core.util;

import java.util.zip.*;
import java.util.*;
import java.net.*;
import java.io.*;

public class JarUtils {
    public static final String[] DLE_FILES;

    public static String doJar(final String jarDir, final String targetJar) {
        final File jarDirFile = new File(jarDir);
        final List<File> files = new ArrayList<File>();
        IoUtils.listFile(files, jarDirFile);
        ZipOutputStream zos = null;
        OutputStream out = null;
        try {
            final File jar = new File(targetJar);
            if (jar.exists()) {
                jar.delete();
            }
            out = new FileOutputStream(jar);
            zos = new ZipOutputStream(out);
            for (final File file : files) {
                if (isDel(file)) {
                    continue;
                }
                String fileName = file.getAbsolutePath().substring(jarDirFile.getAbsolutePath().length() + 1);
                fileName = fileName.replace(File.separator, "/");
                if (file.isDirectory()) {
                    final ZipEntry ze = new ZipEntry(fileName + "/");
                    ze.setTime(System.currentTimeMillis());
                    zos.putNextEntry(ze);
                    zos.closeEntry();
                } else if (fileName.endsWith(".jar")) {
                    final byte[] bytes = IoUtils.readFileToByte(file);
                    final ZipEntry ze2 = new ZipEntry(fileName);
                    ze2.setMethod(0);
                    ze2.setSize(bytes.length);
                    ze2.setTime(System.currentTimeMillis());
                    ze2.setCrc(IoUtils.crc32(bytes));
                    zos.putNextEntry(ze2);
                    zos.write(bytes);
                    zos.closeEntry();
                } else {
                    final ZipEntry ze = new ZipEntry(fileName);
                    ze.setTime(System.currentTimeMillis());
                    zos.putNextEntry(ze);
                    final byte[] bytes2 = IoUtils.readFileToByte(file);
                    zos.write(bytes2);
                    zos.closeEntry();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IoUtils.close(zos, out);
        }
        return targetJar;
    }

    public static List<String> unJar(final String jarPath, final String targetDir) {
        return unJar(jarPath, targetDir, null);
    }

    public static List<String> unJar(final String jarPath, final String targetDir, final List<String> includeFiles) {
        final List<String> list = new ArrayList<String>();
        final File target = new File(targetDir);
        if (!target.exists()) {
            target.mkdirs();
        }
        final FileInputStream fin = null;
        ZipFile zipFile = null;
        try {
            zipFile = new ZipFile(new File(jarPath));
            Enumeration<?> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                final ZipEntry entry = (ZipEntry) entries.nextElement();
                if (entry.isDirectory()) {
                    final File targetFile = new File(target, entry.getName());
                    if (targetFile.exists()) {
                        continue;
                    }
                    targetFile.mkdirs();
                } else {
                    final int lastSeparatorIndex = entry.getName().lastIndexOf("/");
                    if (lastSeparatorIndex <= 0) {
                        continue;
                    }
                    final File targetFile = new File(target, entry.getName().substring(0, lastSeparatorIndex));
                    if (targetFile.exists()) {
                        continue;
                    }
                    targetFile.mkdirs();
                }
            }
            entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                final ZipEntry entry = (ZipEntry) entries.nextElement();
                if (entry.isDirectory()) {
                    continue;
                }
                final File targetFile = new File(target, entry.getName());
                if (includeFiles != null && includeFiles.size() > 0 && !includeFiles.contains(targetFile.getName())) {
                    continue;
                }
                final byte[] bytes = IoUtils.toBytes(zipFile.getInputStream(entry));
                IoUtils.writeFile(targetFile, bytes);
                list.add(targetFile.getAbsolutePath());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IoUtils.close(zipFile, fin);
        }
        return list;
    }

    public static String releaseFileFromJar(final File zip, final String fileName, final File targetFile) {
        final byte[] bytes = getFileFromJar(zip, fileName);
        if (bytes == null) {
            return null;
        }
        IoUtils.writeFile(targetFile, bytes);
        return targetFile.getAbsolutePath();
    }

    public static byte[] getFileFromJar(final File zip, final String fileName) {
        ZipFile zipFile = null;
        try {
            if (!zip.exists()) {
                return null;
            }
            zipFile = new ZipFile(zip);
            final ZipEntry zipEntry = zipFile.getEntry(fileName);
            if (zipEntry == null) {
                return null;
            }
            final InputStream is = zipFile.getInputStream(zipEntry);
            return IoUtils.toBytes(is);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IoUtils.close(zipFile);
        }
        return null;
    }

    public static boolean isDel(final File file) {
        for (final String f : JarUtils.DLE_FILES) {
            if (file.getAbsolutePath().endsWith(f)) {
                return true;
            }
        }
        return false;
    }

    public static String getRootPath(String path) {
        if (path == null) {
            path = JarUtils.class.getResource("").getPath();
        }
        try {
            path = URLDecoder.decode(path, "utf-8");
        } catch (UnsupportedEncodingException ex) {
        }
        if (path.startsWith("jar:") || path.startsWith("war:")) {
            path = path.substring(4);
        }
        if (path.startsWith("file:")) {
            path = path.substring(5);
        }
        if (path.contains("*")) {
            return path.substring(0, path.indexOf("*"));
        }
        if (path.contains("WEB-INF")) {
            return path.substring(0, path.indexOf("WEB-INF"));
        }
        if (path.contains("!")) {
            return path.substring(0, path.indexOf("!"));
        }
        if (path.endsWith(".jar") || path.endsWith(".war")) {
            return path;
        }
        if (path.contains("/classes/")) {
            return path.substring(0, path.indexOf("/classes/") + 9);
        }
        return null;
    }

    static {
        DLE_FILES = new String[]{".DS_Store", "Thumbs.db"};
    }
}
